package org.onvivals.app.modules.iot.controller;

import cn.hutool.core.comparator.VersionComparator;
import cn.hutool.core.convert.Convert;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onvivals.app.modules.auth.util.SaTokenUtil;
import org.onvivals.app.mqtt.util.PlayUtil;
import org.onvivals.common.exception.BusinessException;
import org.onvivals.common.web.Result;
import org.onvivals.module.iot.entity.IotDevice;
import org.onvivals.module.iot.entity.IotDeviceUser;
import org.onvivals.module.iot.entity.IotFirmware;
import org.onvivals.module.iot.param.BlParam;
import org.onvivals.module.iot.param.MessageParam;
import org.onvivals.module.iot.param.RmsParam;
import org.onvivals.module.iot.param.VoiceParam;
import org.onvivals.module.iot.service.IIotDeviceService;
import org.onvivals.module.iot.service.IIotDeviceUserService;
import org.onvivals.module.iot.service.IIotFirmwareService;
import org.onvivals.module.pms.entity.PmsHistory;
import org.onvivals.module.pms.entity.PmsRole;
import org.onvivals.module.pms.service.IPmsHistoryService;
import org.onvivals.module.pms.service.IPmsRoleService;
import org.onvivals.module.ums.entity.UmsUserRole;
import org.onvivals.module.ums.service.IUmsUserRoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: Mr.ZS
 * @Date: 2024/10/28 下午6:21
 **/
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Tag(name = "小程序:设备管理")
@RequestMapping("/device")
public class IotDeviceController {

	private final IIotDeviceService iotDeviceService;

	private final IIotDeviceUserService iotDeviceUserService;

	private final IIotFirmwareService iotFirmwareService;

	private final PlayUtil playUtil;

	private final IUmsUserRoleService userRoleService;

	private final IPmsHistoryService pmsHistoryService;

	private final IPmsRoleService pmsRoleService;

	/**
	 * 查询设备列表
	 */
	@Operation(summary = "查询设备列表")
	@RequestMapping(value = "/checkDevice", method = RequestMethod.GET)
	public Result<?> checkDevice() {
		Long userId = SaTokenUtil.getUserId();
		List<IotDevice> list = iotDeviceService.list(Wrappers.<IotDevice>lambdaQuery().eq(IotDevice::getUserId, userId));
		return Result.OK("查询成功", list);
	}

	/**
	 * 解绑设备
	 */
	@GetMapping("/unbind/{deviceNum}")
	@Operation(summary = "解绑设备")
	public Result<?> unbind(@PathVariable String deviceNum) {
		log.info("解绑设备 deviceNum:{}", deviceNum);
		Long userId = SaTokenUtil.getUserId();
		IotDevice device = iotDeviceService.selectDeviceBySerialNumber(deviceNum, userId);
		Map<String, Object> map = new HashMap<>();
		if (device != null) {
			device.setUserId(null);
			device.setUserName(null);
			iotDeviceService.updateById(device);
			map.put("message", "解绑成功");
			map.put("code", 200);
//			client.publish("/" + productId + "/" + deviceNum + "/unbind/get", JSON.toJSONString(map).getBytes());
			return Result.OK("解绑成功");
		}
		map.put("message", "解绑失败");
		map.put("code", 500);
//		client.publish("/" + productId + "/" + deviceNum + "/unbind/get", JSON.toJSONString(map).getBytes());
		return Result.OK("解绑失败");
	}

	/**
	 * 修改设备的蓝牙设备码
	 */
	@PostMapping("/updateDeviceCode")
	@Operation(summary = "修改设备的设备码")
	private Result<?> updateDeviceCode(@RequestBody BlParam param) {
		log.info("修改设备的设备码 param:{}", JSONUtil.toJsonStr(param));
		IotDevice iotDevice = iotDeviceService.getOne(Wrappers.<IotDevice>lambdaQuery().eq(IotDevice::getSerialNumber, param.getDeviceNumber()));
		iotDevice.setBlId(param.getBlId());
		iotDeviceService.updateById(iotDevice);
		return Result.OK("修改成功");
	}

	/**
	 * 获取设备详情
	 */
	@GetMapping("/getDeviceDetail/{deviceNum}")
	@Operation(summary = "获取设备详情")
	public Result<?> getDeviceDetail(@PathVariable String deviceNum) {
		IotDevice device = iotDeviceService.getById(deviceNum);
		if (device != null) {
			IotDeviceUser deviceUser = iotDeviceUserService.getOne(Wrappers.<IotDeviceUser>lambdaQuery().eq(IotDeviceUser::getDeviceId, device.getDeviceId()));
			if (deviceUser != null) {
				device.setDeviceUser(deviceUser);
			}
			//获取设备的版本号
			BigDecimal firmwareVersion = device.getFirmwareVersion();
			//获取最新的版本
			IotFirmware iotFirmware = iotFirmwareService.getOne(Wrappers.<IotFirmware>lambdaQuery().orderBy(true, false, IotFirmware::getVersion), false);
			Double version = iotFirmware.getVersion();
			//判断是否一致
			int compare = VersionComparator.INSTANCE.compare(Convert.toStr(firmwareVersion), Convert.toStr(version));
			if (compare != 0) {
				device.setLastFirmwareId(iotFirmware.getFirmwareId());
			}
		}
		return Result.OK("查询成功", device);
	}

	/**
	 * 保存或者修改设备用户信息
	 */
	@PostMapping("/saveDeviceUser")
	@Operation(summary = "保存或者修改设备用户信息")
	public Result<?> saveDeviceUser(@RequestBody IotDevice device) {
		IotDevice iotDevice = iotDeviceService.getById(device.getDeviceId());
		iotDevice.setImgUrl(device.getImgUrl());
		iotDevice.setDeviceName(device.getDeviceName());
		iotDeviceService.updateById(iotDevice);
		//iotDeviceUserService.remove(Wrappers.<IotDeviceUser>lambdaQuery().eq(IotDeviceUser::getDeviceId, device.getDeviceId()));
//		IotDeviceUser deviceUser = device.getDeviceUser();
//		deviceUser.setId(null);
//		iotDeviceUserService.save(deviceUser);
		return Result.OK("保存成功");
	}

	/**
	 * ota升级
	 */
	@GetMapping("/otaFirmware/{deviceNum}")
	@Operation(summary = "ota升级")
	public Result<?> otaFirmware(@PathVariable String deviceNum) {
		log.info("ota升级 deviceNum:{}", deviceNum);
		IotDevice iotDevice = iotDeviceService.selectDeviceBySerialNumber(deviceNum);
		if (iotDevice != null) {
			//获取设备的版本号
			BigDecimal firmwareVersion = iotDevice.getFirmwareVersion();
			//获取最新的版本
			IotFirmware iotFirmware = iotFirmwareService.getOne(Wrappers.<IotFirmware>lambdaQuery().orderBy(true, false, IotFirmware::getVersion), false);
			Double version = iotFirmware.getVersion();
			//判断是否一致
			int compare = VersionComparator.INSTANCE.compare(Convert.toStr(firmwareVersion), Convert.toStr(version));
			if (compare == 0) {
				return Result.OK("已是最新版本");
			} else {
				System.out.println("不一致");
				//升级
				String url = iotFirmware.getFilePath();
				playUtil.ota(iotDevice.getSerialNumber(), url);
				return Result.OK("升级推送成功");
			}
		}
		return Result.OK("升级推送成功");
	}


	/**
	 * 使用角色以及个性
	 */
	@GetMapping("/use/{deviceNum}")
	@Operation(summary = "使用角色以及个性")
	public Result<?> use(@PathVariable String deviceNum, Long roleId, Long individualityId) {
		Long userId = SaTokenUtil.getUserId();
		IotDevice iotDevice = iotDeviceService.selectDeviceBySerialNumber(deviceNum);
		if (iotDevice == null) {
			throw new BusinessException("设备不存在");
		}
		//查询是否有
		UmsUserRole umsUserRole = userRoleService.getOne(Wrappers.<UmsUserRole>lambdaQuery().eq(UmsUserRole::getUserId, userId).eq(UmsUserRole::getRoleId, roleId));
		if (umsUserRole != null) {
			iotDevice.setRoleId(roleId);
			iotDevice.setIndividualityId(individualityId);
			PmsRole pmsRole = pmsRoleService.getById(roleId);
			iotDevice.setImgUrl(pmsRole.getImgUrl());
			iotDeviceService.updateById(iotDevice);
		}
		pmsHistoryService.remove(Wrappers.<PmsHistory>lambdaQuery().eq(PmsHistory::getDeviceId, iotDevice.getSerialNumber()));
		return Result.OK("使用角色以及个性");
	}

	/**
	 * 查询设备是否在线
	 */
	@GetMapping("/isOnline/{deviceNum}")
	@Operation(summary = "查询设备是否在线")
	public Result<?> isOnline(@PathVariable String deviceNum) {
		IotDevice iotDevice = iotDeviceService.selectDeviceBySerialNumber(deviceNum);
		if (iotDevice != null) {
			if (3 == iotDevice.getStatus()) {
				return Result.OK(iotDevice.getStatus());
			}
		}
		return Result.OK(4);
	}

	/**
	 * 修改设备音量
	 */
	@PostMapping("/updateDeviceVolume")
	@Operation(summary = "修改设备音量")
	public Result<?> updateDeviceVolume(@RequestBody VoiceParam param) {
		IotDevice iotDevice = iotDeviceService.getOne(Wrappers.<IotDevice>lambdaQuery().eq(IotDevice::getSerialNumber, param.getDeviceNumber()));
		if (iotDevice != null) {
			iotDevice.setVolume(param.getVolume());
			iotDeviceService.updateById(iotDevice);
			playUtil.info(iotDevice.getSerialNumber(), param.getVolume());
		}
		return Result.OK("修改成功");
	}

	/**
	 * 设备注册接口
	 */
	@PostMapping("/register")
	@Operation(summary = "设备注册接口")
	public Result<?> register(@RequestBody IotDevice iotDevice) {
		Long userId = SaTokenUtil.getUserId();
		String deviceNumber = iotDevice.getSerialNumber();
		String code = iotDevice.getCode();
		if (!"0".equals(deviceNumber)){
			IotDevice iotDevice1 = iotDeviceService.autoDevice(deviceNumber, userId, code, iotDevice.getBlId());
			return Result.OK("注册成功", iotDevice1);
		}
		return Result.error("注册失败");
	}

	/**
	 * 设定设备时间
	 */
	@PostMapping("/setTime")
	@Operation(summary = "设定设备时间")
	public Result<?> setTime(@RequestBody MessageParam messageParam) {
		String deviceNum = messageParam.getDeviceNumber();
		IotDevice iotDevice = iotDeviceService.getOne(Wrappers.<IotDevice>lambdaQuery().eq(IotDevice::getSerialNumber, deviceNum));
		if (iotDevice != null) {
			String time = messageParam.getHour() +":"+ messageParam.getMinute();
			iotDevice.setHour(messageParam.getHour());
			iotDevice.setMinute(messageParam.getMinute());
			iotDevice.setTime(time);
			iotDevice.setContent(messageParam.getContent());
			iotDeviceService.updateById(iotDevice);
		}
		return Result.OK("设置成功");
	}

	/**
	 * 修改设备音量
	 */
	@PostMapping("/updateDeviceRms")
	@Operation(summary = "修改设备灵敏度")
	public Result<?> updateDeviceRms(@RequestBody RmsParam param) {
		IotDevice iotDevice = iotDeviceService.getOne(Wrappers.<IotDevice>lambdaQuery().eq(IotDevice::getSerialNumber, param.getDeviceNumber()));
		if (iotDevice != null) {
			iotDevice.setRms(param.getRms());
			iotDeviceService.updateById(iotDevice);
			playUtil.infoRms(iotDevice.getSerialNumber(), param.getRms());
		}
		return Result.OK("修改成功");
	}


}
